/*******************************************************************************
* Signavio Core Components
* Copyright (C) 2012 Signavio GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.hpi.bpmn2_0.factory.node;
import org.oryxeditor.server.diagram.generic.GenericShape;
import de.hpi.bpmn2_0.annotations.StencilId;
import de.hpi.bpmn2_0.exceptions.BpmnConverterException;
import de.hpi.bpmn2_0.factory.AbstractShapeFactory;
import de.hpi.bpmn2_0.factory.BPMNElement;
import de.hpi.bpmn2_0.factory.configuration.Configuration;
import de.hpi.bpmn2_0.model.BaseElement;
import de.hpi.bpmn2_0.model.Definitions;
import de.hpi.bpmn2_0.model.FlowElement;
import de.hpi.bpmn2_0.model.artifacts.Artifact;
import de.hpi.bpmn2_0.model.bpmndi.BPMNShape;
import de.hpi.bpmn2_0.model.choreography.CallChoreography;
import de.hpi.bpmn2_0.model.choreography.Choreography;
import de.hpi.bpmn2_0.model.choreography.ChoreographyActivity;
import de.hpi.bpmn2_0.model.choreography.ChoreographyLoopType;
import de.hpi.bpmn2_0.model.choreography.ChoreographyTask;
import de.hpi.bpmn2_0.model.choreography.SubChoreography;
import de.hpi.bpmn2_0.model.extension.signavio.SignavioMetaData;
/**
* Factory that creates elements of a choreography diagram.
*
* @author Sven Wagner-Boysen
*
*/
@StencilId({
"ChoreographyTask",
"ChoreographySubprocessCollapsed",
"ChoreographySubprocessExpanded"
})
public class ChoreographyActivityFactory extends AbstractShapeFactory {
public BPMNElement createBpmnElement(GenericShape shape, Configuration configuration) throws BpmnConverterException {
BPMNElement bpmnElement = super.createBpmnElement(shape, configuration);
if(bpmnElement != null) {
handleLinkedDiagrams(bpmnElement.getNode(), shape, configuration);
}
return bpmnElement;
}
/* (non-Javadoc)
* @see de.hpi.bpmn2_0.factory.AbstractBpmnFactory#createProcessElement(org.oryxeditor.server.diagram.Shape)
*/
// @Override
protected ChoreographyActivity createProcessElement(GenericShape shape)
throws BpmnConverterException {
try {
ChoreographyActivity activity = (ChoreographyActivity) this.invokeCreatorMethod(shape);
activity.setId(shape.getResourceId());
activity.setName(shape.getProperty("name"));
/* Call choreography */
String isCallActivity = shape.getProperty("callacitivity");
if(isCallActivity != null && isCallActivity.equals("true")) {
activity = new CallChoreography(activity);
}
/* Loop type */
String loopType = shape.getProperty("looptype");
if(loopType != null) {
if(loopType.equalsIgnoreCase("None")) {
activity.setLoopType(ChoreographyLoopType.NONE);
}
else if(loopType.equalsIgnoreCase("Standard")) {
activity.setLoopType(ChoreographyLoopType.STANDARD);
}
else if(loopType.equalsIgnoreCase("MultiInstance")) {
activity.setLoopType(ChoreographyLoopType.MULTI_INSTANCE_PARALLEL);
}
else if(loopType.equalsIgnoreCase("Sequential")) {
activity.setLoopType(ChoreographyLoopType.MULTI_INSTANCE_SEQUENTIAL);
}
}
return activity;
} catch (Exception e) {
/* Wrap exceptions into specific BPMNConverterException */
throw new BpmnConverterException(
"Error while creating the process element of "
+ shape.getStencilId(), e);
}
}
/**
* Creator method for a choreography task.
*
* @param shape
* The resource shape
* @return
* the {@link ChoreographyTask}
*/
@StencilId("ChoreographyTask")
public ChoreographyTask createChoreographyTask(GenericShape shape) {
return new ChoreographyTask();
}
/**
* Creator method for a collapsed choreography subprocess.
*
* @param shape
* The resource shape
* @return
* the {@link SubChoreography}
*/
@StencilId({
"ChoreographySubprocessCollapsed",
"ChoreographySubprocessExpanded"
})
public SubChoreography createChoreographySubprocessCollapsed(GenericShape shape) {
return new SubChoreography();
}
// @Override
protected BPMNShape createDiagramElement(GenericShape shape) {
BPMNShape diagramElement = super.createDiagramElement(shape);
/* Expanded subprocess */
if(shape.getStencilId().equals("ChoreographySubprocessExpanded")) {
diagramElement.setIsExpanded(Boolean.TRUE);
}
/* Collapsed subprocess */
else if(shape.getStencilId().equals("ChoreographySubprocessCollapsed")) {
diagramElement.setIsExpanded(Boolean.FALSE);
}
return diagramElement;
}
/**
* Transforms linked diagrams of collapsed subprocess and event subprocess.
*
* @param baseElement
* @param shape
* @param config
*/
private void handleLinkedDiagrams(BaseElement baseElement, GenericShape shape, Configuration config) {
if(baseElement == null || !(baseElement instanceof SubChoreography) || !shape.getStencilId().matches(".*Collapsed.*")) {
return;
}
/*
* Diagram Link
*/
String entry = shape.getProperty("entry");
if(entry == null || entry.length() == 0) {
return;
}
SignavioMetaData metaData = new SignavioMetaData("entry", entry);
baseElement.getOrCreateExtensionElements().add(metaData);
Definitions linkedDiagram = SubprocessFactory.retrieveDefinitionsOfLinkedDiagram(entry, config);
if(linkedDiagram == null || linkedDiagram.getRootElement().size() == 0) {
return;
}
for(BaseElement rootEl : linkedDiagram.getRootElement()) {
if(rootEl instanceof Choreography) {
Choreography linkedChoreo = (Choreography) rootEl;
/* Sub choreography */
if(baseElement instanceof SubChoreography) {
SubChoreography subChoreography = (SubChoreography) baseElement;
/*
* Add flow elements and artifacts including their diagram
* elements
*/
for(FlowElement flowEl : linkedChoreo.getFlowElement()) {
subChoreography.getFlowElement().add(flowEl);
subChoreography._diagramElements.add(flowEl._diagramElement);
}
for(Artifact artifact : linkedChoreo.getArtifact()) {
subChoreography.getArtifact().add(artifact);
subChoreography._diagramElements.add(artifact._diagramElement);
}
}
/* Call choreography */
else if(baseElement instanceof CallChoreography) {
CallChoreography callChoreography = (CallChoreography) baseElement;
callChoreography.setCalledChoreographyRef(linkedChoreo);
for(BaseElement baseEl : linkedChoreo.getChilds()) {
callChoreography._diagramElements.add(baseEl._diagramElement);
}
}
}
}
}
}